/*
 * @Author: tpy、yjw、hjj
 * @Date: 2020-06-02 15:00:01
 * @LastEditTime: 2020-07-08 21:11:16
 * @LastEditors: 最后修改者
 * @Description: 平台Geojson数据符号化相关
 */ 

const {
    center,
    polygon,
    area,
} = require("@turf/turf");
const Cesium = window.Cesium;
const {CesiumFun} = require("./CesiumFun");
let urls;
let param = new Object();
let labelListener = undefined;
const SZLABEL = "XZBJlabel";
const xzqa = 0.6, SQXZBJOP = 0.7, SQLABELOP = 0.4;
const COMHEIGHT = 10, ENABLED = true, PIXELRANGE = 10, MINCLUSTERSIZE = 2;
const GLOWNUM = 0.15;

/**
 * @description GeoJson实体符号化相关类
 * @author tpy、yjw
 * @annotator hjj
 * @date 2020-06-03
 * @class EntityThematic
 */
class EntityThematic {
    constructor() {
        
        if (window.URLSERVER) {
            urls = window.URLSERVER;
        }
        if (urls && urls.length > 0) {
            for (let i = 0; i < urls.length; i++) {
                param[urls[i].key] = urls[i];
            }
        }
    }

    /**
     * @description 专题数据符号化（GeoJson加载完成后回调）
     * @author tpy、yjw
     * @annotator hjj
     * @date 2020-06-03
     * @param {Cesium.GeoJsonDataSource} datascource geojson数据源
     * @memberof EntityThematic
     */
    ThematicMaterical(datascource) {
        try {
            let pDSname = datascource.name;
            let layerObj = param[pDSname];
            if (layerObj.show !== false) {
                datascource.show = true;
            } else {
                datascource.show = false;
            }
            this._SignifyingByProps(datascource);//通用符号化方法
            let layerType = layerObj.layerType;//有交互需求和特殊符号化需求的数据需要特殊处理
            if (layerType) {
                //统一绑定图层名称
                this._bindLayerName(datascource,layerType);
                switch (layerType) {
                    case "XZBJ"://行政边界线和标注处理
                        this._PolygonMake(datascource);
                }
            }
        } catch (e) {
            //debugger
            console.log("专题图加载失败：", e);
        }

    }
    _bindLayerName(datasource,layerName){
        try {
            datasource.GroupName = layerName;
            let entities = datasource.entities.values;
            for (let i = 0; i < entities.length; i++) {
                entities[i].layername = layerName;
            }
        } catch (e) {
            console.log("图层名称绑定失败：", e);
        }
    }

    /**
     * @description 行政边界特殊处理（边界线和标注）
     * @author tpy
     * @annotator hjj
     * @date 2020-06-23
     * @param {Cesium.Datasource} XZDataSource 数据源
     * @memberof EntityThematic
     * @private
     */
    _PolygonMake(XZDataSource) {
        try {
            let Entities = XZDataSource.entities.values;
            let Lines = this.getPolyBound(Entities);
            for (let i = 0; i < Entities.length; i++) {
                this.PolygonCenter(Entities[i], XZDataSource.name);
            }
            if (Lines && Lines.length > 0) {
                for (let j = 0; j < Lines.length; j++) {
                    XZDataSource.entities.add(Lines[j]);
                }
            }
            let pCesiumFun = new CesiumFun();
            let LabelDS = pCesiumFun.getDSByName(SZLABEL);
            this.labelClusterInit(LabelDS);

        } catch (e) {
            console.log("行政区专题图_2加载失败：", e);
        }
    }

    /**
     * @description 提取面图层边界线（只管外边界，不管中空边界）
     * @author tpy
     * @annotator hjj
     * @date 2020-06-23
     * @param {Array.<Entity>} Entitys 实体数组
     * @returns {Array.<Entity>} 结果数组
     * @memberof EntityThematic
     */
    getPolyBound = (Entitys) => {
        let results = [];
        if (Entitys && Entitys.length > 0) {
            for (let i = 0; i < Entitys.length; i++) {
                try {
                    let tempentity = Entitys[i];
                    if (typeof (tempentity) === "object"
                        && typeof (tempentity.polygon) === "object"
                        && typeof (tempentity.polygon.hierarchy) === "object"
                        && typeof (tempentity.polygon.hierarchy._value) === "object"
                        && typeof (tempentity.polygon.hierarchy._value.positions) === "object") {
                        let points = tempentity.polygon.hierarchy._value.positions;
                        let LineEntity = new window.Cesium.Entity({

                            polyline: {
                                positions: points,
                                width: 2,
                                material: new Cesium.PolylineDashMaterialProperty({
                                    color: Cesium.Color.fromCssColorString("#eaffeb"),//.withAlpha(SQXZBJOP),
                                })
                            },
                        });
                        results.push(LineEntity);
                    }
                } catch (e) {
                    console.log("边界提取出错：", Entitys[i]);
                }

            }
        }
        return results;
    }

    /**
     * @description 获取多边形的几何中心
     * @author tpy
     * @annotator hjj
     * @date 2020-06-23
     * @param {Cesium.Entity} entity 多边形实体
     * @param {string} dsname 数据源名称
     * @returns {Cesium.Datasource} 文本标注数据源
     * @memberof EntityThematic
     */
    PolygonCenter = (entity, dsname) => {
        if (typeof (entity) === "object"
            && typeof (entity.polygon) === "object"
            && typeof (entity.polygon.hierarchy) === "object"
            && typeof (entity.polygon.hierarchy._value) === "object"
            && typeof (entity.polygon.hierarchy._value.positions) === "object") {
            let pCesiumFun = new CesiumFun();
            let LabelDS = pCesiumFun.dsgetbyname(SZLABEL);
            let positions = entity.polygon.hierarchy._value.positions;
            let props = entity.properties.getValue("");
            if (positions && positions.length > 0) {
                let positionArr = [];
                for (let k = 0; k < positions.length; k++) {
                    let itemcart = positions[k];
                    let itemlnglat = pCesiumFun.convertCartesian3ToCarto(itemcart);
                    positionArr.push([itemlnglat.lon, itemlnglat.lat]);
                }
                let labelopc = SQLABELOP;
                let textopc = 0.9
                if (props.material == "#F0F8FF" || props.material == "#0033FF") {
                    labelopc = 0.2;
                    textopc = 0.6;
                } else {
                    console.log(labelopc, "and", textopc);
                }
                if (positionArr.length > 3) {
                    positionArr.push(positionArr[0]);
                    let tpolygon = polygon([positionArr]);
                    let pcenter = center(tpolygon);
                    let areanum = area(tpolygon);
                    let lon = pcenter.geometry.coordinates[0];
                    let lat = pcenter.geometry.coordinates[1];
                    if (props.name === "东江下游片区") {//业主要求修改标注位置 
                        lon -= 0.02;
                        lat += 0.03;
                    }
                    let tlabel = new Cesium.Entity({
                        name: dsname,
                        position: new Cesium.Cartesian3.fromDegrees(lon, lat, 10),
                        label: {
                            text: props.name,
                            font: '32px sans-serif',
                            scale: 0.5,
                            fillColor: Cesium.Color.WHITE.withAlpha(textopc),
                            outlineColor: Cesium.Color.BLACK.withAlpha(labelopc),
                            outlineWidth: 2,
                            showBackground: true,
                            pixelOffset: new Cesium.Cartesian2(0.0, -10),
                            backgroundColor: Cesium.Color.fromCssColorString('#081734').withAlpha(labelopc),
                            style: Cesium.LabelStyle.FILL_AND_OUTLINE
                        },
                        properties: {
                            areas: areanum,
                            text: props.name,
                            centerlnglat: { lng: pcenter.geometry.coordinates[0], lat: pcenter.geometry.coordinates[1] }
                        }
                    });
                    LabelDS.entities.add(tlabel);
                }

            }
            return LabelDS;
        }
    }

    /**
     * @description 文本标注聚类
     * @author tpy
     * @annotator hjj
     * @date 2020-06-23
     * @param {Cesium.Datasource} dsCluster 文本标注数据源
     * @returns {Cesium.Datasource}
     * @memberof EntityThematic
     */
    labelClusterInit =(dsCluster)=>{
        labelListener = undefined;
        dsCluster.clustering.enabled = ENABLED;//2020-09-16 田泽忠 超图版本升级后，加载报错，因此注释掉该代码
        dsCluster.clustering.pixelRange = PIXELRANGE;
        dsCluster.clustering.minimumClusterSize = MINCLUSTERSIZE;
        if (Cesium.defined(labelListener) && labelListener != null) {
            labelListener();
            labelListener = undefined;
        } else {
            labelListener = dsCluster.clustering.clusterEvent.addEventListener((clusteredEntities, cluster)=>{
                if (dsCluster.show) {
                    cluster.label.show = true;
                    cluster.label.horizontalOrigin = Cesium.HorizontalOrigin.CENTER;
                    cluster.label.verticalOrigin = Cesium.VerticalOrigin.BOTTOM;
                    cluster.label.font = "32px sans-serif";
                    cluster.label.scale = 0.5;
                    cluster.label.pixelOffset = new Cesium.Cartesian2(0.0, -10);
                    cluster.label.style = Cesium.LabelStyle.FILL_AND_OUTLINE;
                    cluster.label.showBackground = true;
                    cluster.billboard.show = false;
                    if (clusteredEntities.length >= 2) {
                        let maxvalue = -1, lastentity = null;
                        for (let k = 0; k < clusteredEntities.length; k++) {
                            let tempvalue = clusteredEntities[k].properties.areas.getValue();
                            if (tempvalue > maxvalue) {
                                maxvalue = tempvalue;
                                lastentity = clusteredEntities[k];
                            }
                        }
                        if (lastentity != null) {
                            cluster.label.position = lastentity.position._value;
                            cluster.label.text = lastentity.properties.text._value;
                            try {
                                let topacty = lastentity.label.fillColor.getValue().alpha;
                                // let topacty=1;
                                cluster.label.fillColor = Cesium.Color.WHITE.withAlpha(topacty);
                                cluster.label.backgroundColor = Cesium.Color.fromCssColorString('#081734').withAlpha(topacty);
                            } catch (e) {
                                console.log("xzbj cluster error!");
                            }
                        }
                        // cluster.billboard.image = getSystemConfig().URL_STIMAGE.BASE;
                    }
                } else {
                    console.log("clustering.clusterEvent.addEventListener: hidden");
                }
            });
        }
        let pixelRange = dsCluster.clustering.pixelRange;
        dsCluster.clustering.pixelRange = 0;
        dsCluster.clustering.pixelRange = pixelRange;
        return dsCluster;
    }

    /**
 * @description 根据属性符号化实体
 * @author hjj
 * @date 2020-06-07
 * @param {Cesium.Entity} entity
 * @memberof SCesLayAdd
 * @private
 */
    _SignifyingByProps(dataSource) {
        if (dataSource && dataSource.entities && dataSource.entities.values) {
            let pCesiumFun = new CesiumFun();
            let entityArr = dataSource.entities.values;
            for (let i = 0; i < entityArr.length; i++) {
                let entity = entityArr[i];
                entity.dsname = dataSource.name;
                if (entity.properties) {
                    let props = entity.properties.getValue("");
                    if (entity.polygon) {//面
                        entity.polygon.outline = false;
                        if (props.outline) {
                            entity.polygon.outline = true;
                            let outlineColor = pCesiumFun.convertRGBAToHexadecimal(props.outlineColor);
                            if (outlineColor.color) {                
                                entity.polygon.outlineWidth = props.outlineWidth;
                                entity.polygon.outlineColor = Cesium.Color.fromCssColorString(outlineColor.color).withAlpha(outlineColor.alpha);
                            }
                        }
                        entity.polygon.fill = false;
                        if (props.isFill !== false) {
                            entity.polygon.fill = true;
                            let fillColor = pCesiumFun.convertRGBAToHexadecimal(props.fillColor);
                            if (fillColor.color) {           
                                entity.polygon.material = Cesium.Color.fromCssColorString(fillColor.color).withAlpha(fillColor.alpha);
                            }
                        }
                        if (props.extrudedHeight) {
                            entity.polygon.extrudedHeight = props.extrudedHeight;
                        }
                    } else if (entity.polyline) {//线
                        entity.polyline.width = props.lineWidth || 1;
                        let lineType = props.lineType;
                        let lineColor = pCesiumFun.convertRGBAToHexadecimal(props.lineColor);
                        if (lineColor.color) {
                            switch (lineType) {
                                case "glow"://发光线
                                    entity.polyline.material = new Cesium.PolylineGlowMaterialProperty({
                                        glowPower: 0.15,
                                        color: Cesium.Color.fromCssColorString(lineColor.color).withAlpha(lineColor.alpha)
                                    });
                                    break;
                                case "dash"://虚线
                                    entity.polyline.material = new Cesium.PolylineDashMaterialProperty({
                                        color: Cesium.Color.fromCssColorString(lineColor.color).withAlpha(lineColor.alpha)
                                    });
                                    break;
                                case "arrow"://箭头线
                                    entity.polyline.material = new Cesium.PolylineArrowMaterialProperty(Cesium.Color.fromCssColorString(lineColor.color).withAlpha(lineColor.alpha));
                                    break;
                                default://普通实线
                                    entity.polyline.material = Cesium.Color.fromCssColorString(lineColor.color).withAlpha(lineColor.alpha);
                            }
                        }
                    } else if (entity.billboard) {//点
                        if (props.icon) {
                            let billboard = new Cesium.BillboardGraphics({
                                image: props.icon,//图标地址
                                width: props.width || 12,//宽
                                height: props.height || 12//高
                            });
                            entity.billboard = billboard;
                        }
                    }
                }
            }
        }
    }
}

module.exports = EntityThematic;